﻿
#include "dh/IMVApi.h"

#include "camera_dh.h"
#include <string>
#ifdef _DEBUG
#pragma comment(lib,"dh\\MVSDKmd.lib")
#else
#pragma comment(lib,"dh\\MVSDKmd.lib")
#endif

// 数据帧回调函数
// Data frame callback function
void FrameCallback(IMV_Frame* pFrame, void* pUser)
{
    DhCameraInterface* p = static_cast<DhCameraInterface*>(pUser);

    if (pFrame->pData != nullptr)
    {
        cv::Mat mat_image;
        HObject image;
        if (pFrame->frameInfo.pixelFormat == gvspPixelBayGB8)
        {
//            mat_image = cv::Mat(pFrame->frameInfo.height, pFrame->frameInfo.width, CV_8UC1, pFrame->pData);
//            cv::cvtColor(mat_image, mat_image, cv::COLOR_BayerGR2BGR);
            GenImage1(&image, "byte", (int)pFrame->frameInfo.width, (int)pFrame->frameInfo.height, (Hlong)pFrame->pData);
            CfaToRgb(image, &image, "bayer_gb", "bilinear");
            p->m_CallBack(mat_image,image, p->m_Context);
             return;
        }

        if (pFrame->frameInfo.pixelFormat == gvspPixelBayRG8)
        {
//                int64 t1 = cv::getTickCount();
//                mat_image = cv::Mat(pFrame->frameInfo.height, pFrame->frameInfo.width, CV_8UC1, pFrame->pData);
//                cv::cvtColor(mat_image, mat_image, cv::COLOR_BayerBG2BGR);

                GenImage1(&image, "byte", (int)pFrame->frameInfo.width, (int)pFrame->frameInfo.height, (Hlong)pFrame->pData);
                CfaToRgb(image, &image, "bayer_rg", "bilinear");
//                 int64 t2 = cv::getTickCount();
                p->m_CallBack(mat_image,image, p->m_Context);
                 return;


//                double m_time_use = (t2 - t1) * 1000 / getTickFrequency();
//                logger->info( "aqcuire time:" + std::to_string(m_time_use ));
        }

        if (pFrame->frameInfo.pixelFormat == gvspPixelMono8)
        {
//            mat_image = cv::Mat(pFrame->frameInfo.height, pFrame->frameInfo.width, CV_8UC1, pFrame->pData);
            GenImage1(&image, "byte", (int)pFrame->frameInfo.width, (int)pFrame->frameInfo.height, (Hlong)pFrame->pData);
            p->m_CallBack(mat_image,image, p->m_Context);
            return;
        }
    }
}

// 消息通道事件回调函数
// Message channel event callback function
//static void onMessageChannelEvent(const IMV_SMsgChannelArg* pMsgChannelArg, void* pUser)
//{
//    unsigned int index = 0;
//    const char* pEventIdStr = NULL;

//    if (pMsgChannelArg == NULL)
//    {
//        printf("pMsgChannelArg is NULL\n");
//        return;
//    }

//    switch (pMsgChannelArg->eventId)
//    {
//        case IMV_MSG_EVENT_ID_EXPOSURE_END:pEventIdStr = "ExposureEnd";
//            logger->info("ioExposureEnd");
//            break;
//        case IMV_MSG_EVENT_ID_FRAME_TRIGGER:pEventIdStr = "FrameTrigger"; break;
//        case IMV_MSG_EVENT_ID_FRAME_START:pEventIdStr = "FrameStart"; break;
//        case IMV_MSG_EVENT_ID_ACQ_START:pEventIdStr = "AcquisitionStart"; break;
//        case IMV_MSG_EVENT_ID_ACQ_TRIGGER:pEventIdStr = "AcquisitionTrigger"; break;
//        case IMV_MSG_EVENT_ID_DATA_READ_OUT:pEventIdStr = "ReadOut"; break;
//        default:pEventIdStr = "Unknow"; break;
//    }
//    printf("eventId = [0x%x : %s]\n", pMsgChannelArg->eventId, pEventIdStr);
//    printf("channelId = %u\n", pMsgChannelArg->channelId);
//    printf("blockId = %llu\n", pMsgChannelArg->blockId);
//    printf("timestamp = %llu\n", pMsgChannelArg->timeStamp);

//    for (index = 0; index < pMsgChannelArg->nParamCnt; index++)
//    {
//        printf("paramName = %s\n", pMsgChannelArg->pParamNameList[index].str);
//    }

//    printf("\n");
//    return;
//}


bool DhCameraInterface::camera_init(char* name, CameraCallback pfunction, void* pcontext)
{
    logger->info("DhCameraInterface::camera_init");
    int ret = IMV_OK;
    // 发现设备
    // discover camera
    IMV_DeviceList deviceInfoList;
    ret = IMV_EnumDevices(&deviceInfoList, interfaceTypeAll);
    if (IMV_OK != ret)
    {
        logger->info("IMV_EnumDevices");
        return false;
    }

    if (deviceInfoList.nDevNum < 1)
    {
        logger->info("deviceInfoList.nDevNum");
        return false;
    }

    for (unsigned int i = 0; i < deviceInfoList.nDevNum; i++)
    {
        logger->info(deviceInfoList.pDevInfo[i].serialNumber);
        logger->info(name);

        if (strcmp(deviceInfoList.pDevInfo[i].serialNumber, name) == 0)
        {
            // 创建设备句柄
        // Create Device Handle
            ret = IMV_CreateHandle(&m_camera_handle, modeByCameraKey, static_cast<void*>(deviceInfoList.pDevInfo[i].cameraKey));
            if (IMV_OK != ret)
            {
                logger->info("创建设备句柄ng");
                return false;
            }

            // 打开相机
            // Open camera
            ret = IMV_Open(m_camera_handle);
            if (IMV_OK != ret)
            {
                logger->info("打开相机ng");
                return false;
            }

            // 注册数据帧回调函数
            // Register data frame callback function
            ret = IMV_AttachGrabbing(m_camera_handle, FrameCallback, this);
            if (IMV_OK != ret)
            {
                logger->info("注册回调函数ng");
                return false;
            }

//            // 消息事件回调注册
//            // Register message channel event callback function
//            ret = IMV_SubscribeMsgChannelArg(m_camera_handle, onMessageChannelEvent, this);
//            if (IMV_OK != ret)
//            {
//                return false;
//            }

            // 开始拉流
            // Start grabbing
            ret = IMV_StartGrabbing(m_camera_handle);
            if (IMV_OK != ret)
            {
                logger->info("开始拉流ng");
                return false;
            }
            m_CallBack = pfunction;
            m_Context = pcontext;
            return true;
        }
    }
    if (m_camera_handle == nullptr)
    {
        return false;
    }
    return true;
}

bool DhCameraInterface::camera_end()
{
    if (m_camera_handle == nullptr)
    {
        return false;
    }
    // 停止拉流
        // Stop grabbing
    int ret = IMV_StopGrabbing(m_camera_handle);
    if (IMV_OK != ret)
    {
        return false;
    }

    // 关闭相机
    // Close camera
    ret = IMV_Close(m_camera_handle);
    if (IMV_OK != ret)
    {
        return false;
    }
    return true;
}



bool DhCameraInterface::softwareTrigger()
{
    int ret = IMV_OK;

    ret = IMV_ExecuteCommandFeature(m_camera_handle, "TriggerSoftware");
    if (IMV_OK != ret)
    {
        return false;
    }
    return true;
}

bool DhCameraInterface::setExposureTime(double value)
{
    int ret = IMV_OK;

    ret = IMV_SetDoubleFeatureValue(m_camera_handle, "ExposureTime", value);
    if (IMV_OK != ret)
    {
        return false;
    }

    return true;
}

bool DhCameraInterface::setGainValue(double value)
{
    int ret = IMV_OK;

    ret = IMV_SetDoubleFeatureValue(m_camera_handle, "GainRaw", value);
    if (IMV_OK != ret)
    {
        return false;
    }
    return true;
}

bool DhCameraInterface::getExposureTime(double& value)
{
     return false;
}

bool DhCameraInterface::getGainValue(double& value)
{
    return false;
}

bool DhCameraInterface::setTriggerMode(std::string name)
{
    // 设置触发模式

    int ret = IMV_SetEnumFeatureSymbol(m_camera_handle, "TriggerMode", name.c_str());
    if (IMV_OK != ret)
    {
        return false;
    }
    return true;
}

bool DhCameraInterface::setTriggerSource(std::string name)
{
    int ret = IMV_SetEnumFeatureSymbol(m_camera_handle, "TriggerSource", name.c_str());
    if (IMV_OK != ret)
    {
        return false;
    }
    return true;
}

CameraInterface* newInstance()
 {
     DhCameraInterface* instance = new DhCameraInterface();
     return static_cast<CameraInterface*>(instance);
 }
